﻿using System;
using System.Collections.Generic;
using System.Text;
using BCMS.DAL.IDAL;
using BCMS.Business.DataContract;
using BCMS.Settings;
using BCMS.FrontEnd.DataContract;

namespace BCMS.Business.Implementation
{
    public class DataAccessClient
    {
        ICoupon dalCoupon;
        IRelease dalRelease;
        ILog dalLog;
        IUser dalUser;
        IOther dalOther;

        #region Coupon
        public int insertCoupon(string serial, DateTime start, DateTime expire, decimal parValue, int status, string note, int releaseId, bool isCanceled)
        {
            dalCoupon = BCMS.DAL.Factory.CouponFactory.Create(Params.DB_TYPE);
            try
            {
                dalCoupon.Open(Params.DB_CNN);
                return dalCoupon.insertCoupon(serial, start, expire, parValue, status, note, releaseId, isCanceled);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalCoupon.Close();
            }
        }

        public List<CouponInfo> getCouponsByClaim(int? claimBy, string serial, DateTime from, DateTime to)
        {
            dalCoupon = BCMS.DAL.Factory.CouponFactory.Create(Params.DB_TYPE);
            try
            {
                dalCoupon.Open(Params.DB_CNN);
                return dalCoupon.getCouponsByClaim(claimBy, serial, from, to);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalCoupon.Close();
            }
        }

        public CouponInfo GetCouponBySerial(string serial)
        {
            dalCoupon = BCMS.DAL.Factory.CouponFactory.Create(Params.DB_TYPE);
            try
            {
                dalCoupon.Open(Params.DB_CNN);
                return dalCoupon.getCouponBySerial(serial);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalCoupon.Close();
            }
        }

        public List<CouponInfo> getCoupons(string serial, int status)
        {
            dalCoupon = BCMS.DAL.Factory.CouponFactory.Create(Params.DB_TYPE);
            try
            {
                dalCoupon.Open(Params.DB_CNN);
                return dalCoupon.getCoupons(serial, status);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalCoupon.Close();
            }
        }

        public void deleteCouponByReleaseId(int releaseId)
        {
            dalCoupon = BCMS.DAL.Factory.CouponFactory.Create(Params.DB_TYPE);
            try
            {
                dalCoupon.Open(Params.DB_CNN);
                dalCoupon.deleteCouponByReleaseId(releaseId);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalCoupon.Close();
            }
        }

        public void deleteCouponBySerials(string serial)
        {
            dalCoupon = BCMS.DAL.Factory.CouponFactory.Create(Params.DB_TYPE);
            try
            {
                dalCoupon.Open(Params.DB_CNN);
                dalCoupon.deleteCouponBySerial(serial);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalCoupon.Close();
            }
        }

        public int claimCouponBySerial(string serial, int userid, string note, DateTime claimDate)
        {
            dalCoupon = BCMS.DAL.Factory.CouponFactory.Create(Params.DB_TYPE);
            try
            {
                dalCoupon.Open(Params.DB_CNN);
                return dalCoupon.claimCouponBySerial(serial, userid, note, claimDate);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalCoupon.Close();
            }
        }

        public void batchClaim(List<string> serials, int userid, string note, DateTime claimDate)
        {
            dalCoupon = BCMS.DAL.Factory.CouponFactory.Create(Params.DB_TYPE);
            dalCoupon.Open(Params.DB_CNN);
            dalCoupon.BeginADOTransaction();
            try
            {
                foreach (string serial in serials)
                {
                    CouponInfo item = dalCoupon.getCouponBySerial(serial);
                    if (item != null && item.Status != (int)CStatus.Claimed)
                    {
                        dalCoupon.claimCouponBySerial(serial, userid, note, claimDate);
                        System.Threading.Thread.Sleep(100);
                    }
                    else
                        throw new InvalidOperationException();
                }
                dalCoupon.CommitADOTransaction();
            }
            catch (Exception ex)
            {
                dalCoupon.RollBackTransaction();
                throw ex;
            }
            finally
            {
                dalCoupon.Close();
            }
        }

        public void batchDelete(List<string> serials)
        {

        }


        public int extendCouponBySerial(string serial, string note, DateTime expireDate)
        {
            dalCoupon = BCMS.DAL.Factory.CouponFactory.Create(Params.DB_TYPE);
            try
            {
                dalCoupon.Open(Params.DB_CNN);
                return dalCoupon.extendCouponBySerial(serial, note, expireDate);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalCoupon.Close();
            }
        }

        public void batchCouponExtend(List<string> serials, string note, DateTime expireDate)
        {
            dalCoupon = BCMS.DAL.Factory.CouponFactory.Create(Params.DB_TYPE);
            dalCoupon.Open(Params.DB_CNN);
            dalCoupon.BeginADOTransaction();
            try
            {
                foreach (string serial in serials)
                {
                    CouponInfo item = dalCoupon.getCouponBySerial(serial);
                    if (item != null && item.Status != (int)CStatus.Claimed)
                        dalCoupon.extendCouponBySerial(serial, note, expireDate);
                    else
                        throw new InvalidOperationException();
                }
                dalCoupon.CommitADOTransaction();
            }
            catch (Exception ex)
            {
                dalCoupon.RollBackTransaction();
                throw ex;
            }
            finally
            {
                dalCoupon.Close();
            }
        }

        public int undoClaimCouponBySerial(string serial)
        {
            dalCoupon = BCMS.DAL.Factory.CouponFactory.Create(Params.DB_TYPE);
            try
            {
                dalCoupon.Open(Params.DB_CNN);
                return dalCoupon.undoClaimCouponBySerial(serial);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalCoupon.Close();
            }
        }

        public void cancelCouponBySerial(string serial)
        {
            dalCoupon = BCMS.DAL.Factory.CouponFactory.Create(Params.DB_TYPE);
            try
            {
                dalCoupon.Open(Params.DB_CNN);
                dalCoupon.cancelCouponBySerial(serial);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalCoupon.Close();
            }
        }

        public void disposelCouponByReleaseId(int releaseId, int disposeStatus, int normalSatus)
        {
            dalCoupon = BCMS.DAL.Factory.CouponFactory.Create(Params.DB_TYPE);
            try
            {
                dalCoupon.Open(Params.DB_CNN);
                dalCoupon.disposelCouponByReleaseId(releaseId, disposeStatus, normalSatus);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalCoupon.Close();
            }
        }

        public List<CouponInfo> reportExpiredCouponDetail(DateTime fromDate, DateTime toDate, DateTime reportDate)
        {
            dalCoupon = BCMS.DAL.Factory.CouponFactory.Create(Params.DB_TYPE);
            try
            {
                dalCoupon.Open(Params.DB_CNN);
                return dalCoupon.reportExpiredUnClaimed(fromDate, toDate, reportDate);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalCoupon.Close();
            }
        }

        public List<CouponInfo> reportUnexpiredUnclaimed(DateTime fromDate, DateTime toDate, DateTime reportDate)
        {
            dalCoupon = BCMS.DAL.Factory.CouponFactory.Create(Params.DB_TYPE);
            try
            {
                dalCoupon.Open(Params.DB_CNN);
                return dalCoupon.reportUnexpiredUnclaimed(fromDate, toDate, reportDate);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalCoupon.Close();
            }
        }

        public List<CouponInfo> findClaimedCouponsBySeries(DateTime smaller, DateTime greater, int claimby)
        {
            dalCoupon = BCMS.DAL.Factory.CouponFactory.Create(Params.DB_TYPE);
            try
            {
                dalCoupon.Open(Params.DB_CNN);
                return dalCoupon.findClaimedCouponsBySeries(smaller, greater, claimby);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalCoupon.Close();
            }
        }

        public List<CouponBrief> reportClaimedCoupons(DateTime fromDate, DateTime toDate)
        {
            dalCoupon = BCMS.DAL.Factory.CouponFactory.Create(Params.DB_TYPE);
            try
            {
                dalCoupon.Open(Params.DB_CNN);
                return dalCoupon.reportClaimedCoupons(fromDate, toDate);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalCoupon.Close();
            }
        }

        public List<CouponBrief> reportClaimedCouponsByUser(int claimBy, DateTime fromDate, DateTime toDate)
        {
            dalCoupon = BCMS.DAL.Factory.CouponFactory.Create(Params.DB_TYPE);
            try
            {
                dalCoupon.Open(Params.DB_CNN);
                return dalCoupon.reportClaimedCouponsByUser(claimBy, fromDate, toDate);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalCoupon.Close();
            }
        }

        public List<CouponBrief> reportExpireCoupons(DateTime reportDate)
        {
            dalCoupon = BCMS.DAL.Factory.CouponFactory.Create(Params.DB_TYPE);
            try
            {
                dalCoupon.Open(Params.DB_CNN);
                return dalCoupon.reportExpireCoupons(reportDate);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalCoupon.Close();
            }
        }

        public List<CouponBrief> reportUnExpireCoupons(DateTime reportDate)
        {
            dalCoupon = BCMS.DAL.Factory.CouponFactory.Create(Params.DB_TYPE);
            try
            {
                dalCoupon.Open(Params.DB_CNN);
                return dalCoupon.reportUnExpireCoupons(reportDate);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalCoupon.Close();
            }
        }

        public List<CouponBrief> reportCouponsByReleaseDate(DateTime fromDate, DateTime toDate)
        {
            dalCoupon = BCMS.DAL.Factory.CouponFactory.Create(Params.DB_TYPE);
            try
            {
                dalCoupon.Open(Params.DB_CNN);
                return dalCoupon.reportCouponsByReleaseDate(fromDate, toDate);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalCoupon.Close();
            }
        }
        #endregion

        #region Release
        public int insertRelease(string name, DateTime start, DateTime expire, long qtty, decimal parvalue, int target, string detail, string note, int kind, string rcode, long rlow, long rhigh)
        {
            dalRelease = BCMS.DAL.Factory.ReleaseFactory.Create(Params.DB_TYPE);
            try
            {
                dalRelease.Open(Params.DB_CNN);
                return dalRelease.insertRelease(name, start, expire, qtty, parvalue, target, detail, note, kind, rcode, rlow, rhigh);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalRelease.Close();
            }
        }

        public ReleaseInfo getReleaseByName(string name)
        {
            dalRelease = BCMS.DAL.Factory.ReleaseFactory.Create(Params.DB_TYPE);
            try
            {
                dalRelease.Open(Params.DB_CNN);
                return dalRelease.getReleaseByName(name);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalRelease.Close();
            }
        }

        public List<ReleaseInfo> getReleaseByDate(DateTime from, DateTime to)
        {
            dalRelease = BCMS.DAL.Factory.ReleaseFactory.Create(Params.DB_TYPE);
            try
            {
                dalRelease.Open(Params.DB_CNN);
                return dalRelease.getReleaseByDate(from, to);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalRelease.Close();
            }
        }

        public ReleaseInfo getReleaseById(int releaseId)
        {
            dalRelease = BCMS.DAL.Factory.ReleaseFactory.Create(Params.DB_TYPE);
            try
            {
                dalRelease.Open(Params.DB_CNN);
                return dalRelease.getReleaseById(releaseId);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalRelease.Close();
            }
        }

        public List<string> getDetailSuggest()
        {
            dalRelease = BCMS.DAL.Factory.ReleaseFactory.Create(Params.DB_TYPE);
            try
            {
                dalRelease.Open(Params.DB_CNN);
                return dalRelease.getDetailSuggest();
            }
            catch
            {
                throw;
            }
            finally
            {
                dalRelease.Close();
            }
        }

        public void updateReleaseNote(int releaseId, string note)
        {
            dalRelease = BCMS.DAL.Factory.ReleaseFactory.Create(Params.DB_TYPE);
            try
            {
                dalRelease.Open(Params.DB_CNN);
                dalRelease.updateReleaseNote(releaseId, note);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalRelease.Close();
            }
        }
        public void updateReleaseQttyByName(long qtty, string name)
        {
            dalRelease = BCMS.DAL.Factory.ReleaseFactory.Create(Params.DB_TYPE);
            try
            {
                dalRelease.Open(Params.DB_CNN);
                dalRelease.updateReleaseQttyByName(qtty, name);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalRelease.Close();
            }
        }

        public int updateReleaseStatusById(int releaseId, int newStatus, string note)
        {
            dalRelease = BCMS.DAL.Factory.ReleaseFactory.Create(Params.DB_TYPE);
            try
            {
                dalRelease.Open(Params.DB_CNN);
                return dalRelease.updateReleaseStatusById(releaseId, newStatus, note);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalRelease.Close();
            }
        }

        public void updateReleaseById(int releaseId, string name, DateTime start, DateTime expire, long qtty, decimal parvalue, int target, string detail, string note, int kind, string rcode, long rlow, long rhigh)
        {
            dalRelease = BCMS.DAL.Factory.ReleaseFactory.Create(Params.DB_TYPE);
            try
            {
                dalRelease.Open(Params.DB_CNN);
                dalRelease.updateReleaseById(releaseId, name, start, expire, qtty, parvalue, target, detail, note, kind, rcode, rlow, rhigh);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalRelease.Close();
            }
        }

        public void deleteRelease(int releaseId)
        {
            dalRelease = BCMS.DAL.Factory.ReleaseFactory.Create(Params.DB_TYPE);
            try
            {
                dalRelease.Open(Params.DB_CNN);
                dalRelease.deleteRelease(releaseId);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalRelease.Close();
            }
        }

        public List<ReleaseInfo> getAllRelease()
        {
            dalRelease = BCMS.DAL.Factory.ReleaseFactory.Create(Params.DB_TYPE);
            try
            {
                dalRelease.Open(Params.DB_CNN);
                return dalRelease.getReleases();
            }
            catch
            {
                throw;
            }
            finally
            {
                dalRelease.Close();
            }
        }

        public List<ReleaseInfo> searchRelease(string code, long num, long parValue, int kind, int target, string detail, DateTime from, DateTime to)
        {
            dalRelease = BCMS.DAL.Factory.ReleaseFactory.Create(Params.DB_TYPE);
            try
            {
                dalRelease.Open(Params.DB_CNN);
                return dalRelease.searchRelease(code, num, parValue, kind, target, detail, from, to);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalRelease.Close();
            }
        }

        #endregion

        #region Others
        public List<OtherInfo> getOtherInfoListByType(string type)
        {
            dalOther = BCMS.DAL.Factory.OtherFactory.Create(Params.DB_TYPE);
            try
            {
                dalOther.Open(Params.DB_CNN);
                return dalOther.getOtherInfoListByType(type);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalOther.Close();
            }
        }

        public int insertOtherInfo(string type, string name)
        {
            dalOther = BCMS.DAL.Factory.OtherFactory.Create(Params.DB_TYPE);
            try
            {
                dalOther.Open(Params.DB_CNN);
                return dalOther.insertOtherInfo(type, name);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalOther.Close();
            }
        }

        public void importCoupons(ReleaseInfo rls, List<CouponInfo> coupons)
        {
            dalCoupon = BCMS.DAL.Factory.CouponFactory.Create(Params.DB_TYPE);
            dalRelease = BCMS.DAL.Factory.ReleaseFactory.Create(Params.DB_TYPE);
            dalCoupon.Open(Params.DB_CNN);
            dalRelease.Open(Params.DB_CNN);
            dalCoupon.BeginADOTransaction();
            dalRelease.BeginADOTransaction();
            try
            {
                int releaseId = dalRelease.insertRelease(rls.Name, rls.StartDate, rls.ExpireDate, rls.Qtty, rls.ParValue, rls.Target, rls.Detail, rls.Note, rls.Kind, rls.RCode, rls.RLow, rls.RHigh);

                foreach (CouponInfo item in coupons)
                    dalCoupon.insertCoupon(item.Serial, item.StartDate, item.ExpireDate, item.ParValue, item.Status, item.Note, releaseId, item.IsCanceled);

                dalRelease.CommitADOTransaction();
                dalCoupon.CommitADOTransaction();
            }
            catch (Exception ex)
            {
                dalRelease.RollBackTransaction();
                dalCoupon.RollBackTransaction();
                throw ex;
            }
            finally
            {
                dalCoupon.Close();
                dalRelease.Close();
            }
        }

        public void ImportClaimCoupons(List<CouponInfo> coupons)
        {
            dalCoupon = BCMS.DAL.Factory.CouponFactory.Create(Params.DB_TYPE);
            dalCoupon.Open(Params.DB_CNN);
            dalCoupon.BeginADOTransaction();
            try
            {
                foreach (CouponInfo item in coupons)
                {
                    CouponInfo tmp = dalCoupon.getCouponBySerial(item.Serial);
                    if (tmp != null)
                        dalCoupon.claimCouponBySerial(item.Serial, GlobalVars.activeUserId, string.Empty, item.ClaimDate ?? DateTime.Today);
                }

                dalCoupon.CommitADOTransaction();
            }
            catch (Exception ex)
            {
                dalCoupon.RollBackTransaction();
                throw ex;
            }
            finally
            {
                dalCoupon.Close();
            }
        }
        #endregion

        #region Users
        public UserInfo UserLogin(string username, string password)
        {
            dalUser = BCMS.DAL.Factory.UserFactory.Create(Params.DB_TYPE);
            try
            {
                dalUser.Open(Params.DB_CNN);
                return dalUser.login(username, password);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalUser.Close();
            }
        }

        public UserInfo getUserByName(string userName)
        {
            {
                dalUser = BCMS.DAL.Factory.UserFactory.Create(Params.DB_TYPE);
                try
                {
                    dalUser.Open(Params.DB_CNN);
                    return dalUser.getUserByName(userName);
                }
                catch
                {
                    throw;
                }
                finally
                {
                    dalUser.Close();
                }
            }
        }

        public void updateUser(int userId, string fullname, string email, string phone, string address, string position, string department)
        {
            dalUser = BCMS.DAL.Factory.UserFactory.Create(Params.DB_TYPE);
            try
            {
                dalUser.Open(Params.DB_CNN);
                dalUser.updateUserInfo(userId, fullname, email, phone, address, position, department);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalUser.Close();
            }
        }

        public UserInfo getUserById(int userId)
        {
            dalUser = BCMS.DAL.Factory.UserFactory.Create(Params.DB_TYPE);
            try
            {
                dalUser.Open(Params.DB_CNN);
                return dalUser.getUserById(userId);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalUser.Close();
            }
        }

        public void updateUserRoles(int uID, string roles)
        {
            dalUser = BCMS.DAL.Factory.UserFactory.Create(Params.DB_TYPE);
            try
            {
                dalUser.Open(Params.DB_CNN);
                dalUser.updateUserRoles(uID, roles);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalUser.Close();
            }
        }

        public int insertUser(string username, string password, string roles, string fullname, string email, string phone, string address, string position, string department)
        {
            int retVal = 0;
            dalUser = BCMS.DAL.Factory.UserFactory.Create(Params.DB_TYPE);
            try
            {
                dalUser.Open(Params.DB_CNN);
                retVal = dalUser.insertUser(username, password, roles, fullname, email, phone, address, position, department);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalUser.Close();
            }
            return retVal;
        }

        public void ChangePassword(int userID, string newPasword)
        {
            dalUser = BCMS.DAL.Factory.UserFactory.Create(Params.DB_TYPE);
            try
            {
                dalUser.Open(Params.DB_CNN);
                dalUser.changePassword(userID, newPasword);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalUser.Close();
            }
        }

        public List<UserInfo> getAllUsers()
        {
            List<UserInfo> retList = null;
            dalUser = BCMS.DAL.Factory.UserFactory.Create(Params.DB_TYPE);
            try
            {
                dalUser.Open(Params.DB_CNN);
                retList = dalUser.getAllUsers();
            }
            catch
            {
                throw;
            }
            finally
            {
                dalUser.Close();
            }
            return retList;
        }
        #endregion

        #region Log
        public void insertLog(LogInfo item)
        {
            dalLog = BCMS.DAL.Factory.LogFactory.Create(Params.DB_TYPE);
            try
            {
                dalLog.Open(Params.DB_CNN);
                dalLog.insertLog(item);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalLog.Close();
            }
        }

        public void clearLogBeforeDate(DateTime fromDate)
        {
            dalLog = BCMS.DAL.Factory.LogFactory.Create(Params.DB_TYPE);
            try
            {
                dalLog.Open(Params.DB_CNN);
                dalLog.clearLogBeforeDate(fromDate);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalLog.Close();
            }
        }

        public void clearLogByUserId(string userid)
        {
            dalLog = BCMS.DAL.Factory.LogFactory.Create(Params.DB_TYPE);
            try
            {
                dalLog.Open(Params.DB_CNN);
                dalLog.clearLogByUserId(userid);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalLog.Close();
            }
        }

        public List<LogInfo> searchLog(string username, string action, DateTime fromDate, DateTime toDate)
        {
            dalLog = BCMS.DAL.Factory.LogFactory.Create(Params.DB_TYPE);
            try
            {
                dalLog.Open(Params.DB_CNN);
                return dalLog.searchLog(username, action, fromDate, toDate);
            }
            catch
            {
                throw;
            }
            finally
            {
                dalLog.Close();
            }
        }
        #endregion

    }
}
